/**
 * 
 */
package com.mz3co.sysadmin.service.impl;

import com.mz3co.sysadmin.dao.SysAuthenticationInfoMapper;
import com.mz3co.sysadmin.dao.SysEmployeeMapper;
import com.mz3co.sysadmin.dao.SysUsersMapper;
import com.mz3co.sysadmin.model.*;
import com.mz3co.sysadmin.model.SysEmployeeExample.Criteria;
import com.mz3co.sysadmin.model.ex.SysEmployeeEx;
import com.mz3co.sysadmin.page.Page;
import com.mz3co.sysadmin.service.SysEmployeeService;
import com.mz3co.sysadmin.service.utils.DateJsonValueProcessor;
import com.mz3co.sysadmin.service.utils.ExportExcel;
import com.mz3co.sysadmin.service.utils.SysConst;
import com.mz3co.sysadmin.service.utils.SysOrganizationStructureTreeNode;
import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.io.OutputStream;
import java.util.*;

/**
 * Copyright@宁波高新区敏智科技有限公司 www.mz3co.com Copyright@浙江大学软件学院S309实验室
 * 
 * @author chengxl Cteated time：2014年12月31日 上午10:53:56
 * 
 */

public class SysEmployeeServiceImpl implements SysEmployeeService {

	@Autowired
	private SysEmployeeMapper employeeMapper;// SysEmployeeMapperEx

	@Autowired
	private SysUsersMapper usersMapper;

	@Autowired
	private SysAuthenticationInfoMapper authenticationInfoMapper;

	public Map<String, Object> getEmployeeByPage(SysEmployeeEx employee,
			Integer pageSize, Integer pageNow) {
		SysEmployeeExample example = new SysEmployeeExample();
		Criteria criteria = example.createCriteria();
		
		this.setCriteria(employee, criteria);
		
//		criteria.andEmployeeIdIsNotNull();
		int totalrecords = employeeMapper.countByExample(example);

		/**
		 * for my sql db
		 */
		Page page = new Page();

		page.setBegin((pageNow - 1) * pageSize);
		page.setLength(pageSize);

		List<SysEmployee> employees = employeeMapper.selectByExample(example);

		/**
		 * for sql server db
		 */

		// example.setPageIndex(pageNow);
		// example.setPageSize(pageSize);
		// example.setOrderByClause("employee_id desc");
		//
		// List<SysEmployee> employees = employeeMapper.selectPage(example);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("total", totalrecords);
		if (totalrecords % pageSize == 0)
			map.put("totalPages", totalrecords / pageSize);
		else
			map.put("totalPages", totalrecords / pageSize + 1);
		JsonConfig config = new JsonConfig();
		config.setIgnoreDefaultExcludes(false);
		config.registerJsonValueProcessor(Date.class,
				new DateJsonValueProcessor("yyyy-MM-dd HH:mm:ss"));

		map.put("rows", JSONArray.fromObject(this.convert(employees), config));
		return map;
	}
	
	private void setCriteria(SysEmployeeEx employee,Criteria criteria){
		if (!StringUtils.isEmpty(employee.getEmployeeName())) {
			criteria.andEmployeeNameLike("%" + employee.getEmployeeName() + "%");
		}
		if (employee.getDepartmentName() != null
				&& !employee.getDepartmentName().equals("")) {

			List<Integer> osIds = SysConst.ORGANIZATIONSTRUCTURE_TREE
					.getOSIds(employee.getDepartmentName());

			if (osIds.size() == 0)
				osIds.add(-1);

			criteria.andEmployeeDepartmentIn(osIds);
		}
		
	}

	private List<SysEmployeeEx> convert(List<SysEmployee> listE) {

		if (listE == null)
			return null;

		List<SysEmployeeEx> listHE = new ArrayList<SysEmployeeEx>();

		for (SysEmployee e : listE) {
			SysEmployeeEx he = new SysEmployeeEx();
			// ReflectionUtils.parentToChild(e, he);

			BeanUtils.copyProperties(e, he);

			if (e.getEmployeeDepartment() == null
					|| "".equals(e.getEmployeeDepartment()))
				;
			else {
				SysOrganizationStructureTreeNode node = SysConst.ORGANIZATIONSTRUCTURE_TREE
						.getNode(e.getEmployeeDepartment());

				he.setDepartmentName(SysConst.ORGANIZATIONSTRUCTURE_TREE
						.getParentsNodeName(node) + node.getName());

			}

			listHE.add(he);

		}

		return listHE;

	}

	public String insert(SysEmployee employee) {

		if (this.isExist(employee.getEmployeeCellPhone(), employee.getEmail()))
			return "error 用户手机号或邮箱已存在";

		this.doInsert(employee);

		this.init_EMPLOYEEMAP();

		// SysConst.initConstFor_QUERY("init_EMPLOYEEMAP");

		return "success";
	}

	@Transactional
	private boolean doInsert(SysEmployee employee) {

		employeeMapper.insertSelectiveAndGetId(employee);
		int employeeId = employee.getEmployeeId();
		int uid = 0;
		/* 在添加员工信息时，将用户名添加到users表中 */
		// if (employee.getEmployeeName() != null) {
		SysUsers users = new SysUsers();
		users.setUsername(employee.getEmployeeName());
		users.setCreatetime(new Date());
		users.setType("员工");
		users.setUserDetailId(employeeId);
		usersMapper.insertSelectiveAndGetId(users);
		uid = users.getId();
		// }
		/* 将手机号和邮箱分别添加到授权表中，作为登录信息，密码默认为手机号后6位 */
		if (!StringUtils.isEmpty(employee.getEmployeeCellPhone())) {
			// if (employee.getEmployeeCellPhone() != null) {
			SysAuthenticationInfo info = new SysAuthenticationInfo();
			info.setAccount(employee.getEmployeeCellPhone());
			info.setUid(uid);
			info.setType("手机");
			info.setStatus("不启用");
			int length = employee.getEmployeeCellPhone().length();
			info.setPassword(employee.getEmployeeCellPhone().substring(
					length - 6, length));
			authenticationInfoMapper.insertSelective(info);

			if (!StringUtils.isEmpty(employee.getEmail())) {

				SysAuthenticationInfo info2 = new SysAuthenticationInfo();
				info2.setAccount(employee.getEmail());
				info2.setUid(uid);
				info2.setType("邮箱");
				info2.setStatus("不启用");
				info2.setPassword(employee.getEmployeeCellPhone().substring(
						length - 6, length));
				authenticationInfoMapper.insertSelective(info2);
			}

		}

		return true;
	}

	// 判断用户的手机号，或邮箱是否存在
	private boolean isExist(String phone, String email) {

		SysEmployeeExample example = new SysEmployeeExample();

		example.or().andEmployeeCellPhoneEqualTo(phone);
		if (!"".equals(email))
			example.or().andEmailEqualTo(email);

		return employeeMapper.countByExample(example) > 0 ? true : false;
	}

	// 判断用户的手机号是否存在
	private boolean isExistphone(SysEmployee employee) {

		SysEmployeeExample example = new SysEmployeeExample();

		example.or().andEmployeeCellPhoneEqualTo(
				employee.getEmployeeCellPhone());

		List<SysEmployee> employees = employeeMapper.selectByExample(example);

		if (employees.size() < 1)
			return false;

		for (SysEmployee e : employees) {

			if (e.getEmployeeId() == employee.getEmployeeId())
				return false;
		}

		return true;

	}

	// 判断用户的邮箱是否存在
	private boolean isExistEmail(SysEmployee employee) {

		if (employee.getEmail().equals("")) {
			return false;
		}
		SysEmployeeExample example = new SysEmployeeExample();

		example.or().andEmailEqualTo(employee.getEmail());

		List<SysEmployee> employees = employeeMapper.selectByExample(example);

		if (employees.size() < 1)
			return false;

		for (SysEmployee e : employees) {

			if (e.getEmployeeId() == employee.getEmployeeId())
				return false;
		}

		return true;

	}

	public String update(SysEmployee employee) {

		// 判断是否修改了手机号码及邮箱，如果修改了则需要修改相应的user表及authentciaionInfo表
		if (this.isExistphone(employee))
			return "用户手机号已存在";

		// 判断是否修改了手机号码及邮箱，如果修改了则需要修改相应的user表及authentciaionInfo表
		if (this.isExistEmail(employee))
			return "用户邮箱已存在";

		// this.updateUsersAndAuthentication(employee);

		if (employeeMapper.updateByPrimaryKeySelective(employee) < 1)
			return "修改失败";

		this.init_EMPLOYEEMAP();

		// SysConst.initConstFor_QUERY("init_EMPLOYEEMAP");

		return "success";
	}

	@Transactional
	private void updateUsersAndAuthentication(SysEmployee employee) {

		SysEmployee oldEmployee = employeeMapper.selectByPrimaryKey(employee
				.getEmployeeId());

		// 员工姓名修改时，修改user表中的username
		if (!oldEmployee.getEmployeeName().equals(employee.getEmployeeName())) {
			SysUsers user = new SysUsers();

			user.setUsername(employee.getEmployeeName());

			SysUsersExample example = new SysUsersExample();

			example.or().andUserDetailIdEqualTo(employee.getCreatorId())
					.andUsernameEqualTo(oldEmployee.getEmployeeName());

			usersMapper.updateByExampleSelective(user, example);

		}

		// 员工手机修改时，修改user表中的username
		if (!oldEmployee.getEmployeeCellPhone().equals(
				employee.getEmployeeCellPhone())) {
			SysAuthenticationInfo authenInfo = new SysAuthenticationInfo();

			authenInfo.setAccount(employee.getEmployeeCellPhone());

			SysAuthenticationInfoExample example = new SysAuthenticationInfoExample();

			example.or().andAccountEqualTo(oldEmployee.getEmployeeCellPhone());

			authenticationInfoMapper.updateByExampleSelective(authenInfo,
					example);

		}

		// 邮箱修改时，修改authenticationInfo表中的 account
		if (!oldEmployee.getEmail().equals(employee.getEmail())) {

			SysAuthenticationInfo authenInfo = new SysAuthenticationInfo();

			authenInfo.setAccount(employee.getEmail());

			SysAuthenticationInfoExample example = new SysAuthenticationInfoExample();

			example.or().andAccountEqualTo(oldEmployee.getEmail());

			authenticationInfoMapper.updateByExampleSelective(authenInfo,
					example);
		}

	}

	public String deleteEmpById(String[] ids) {
		for (String id : ids) {
			try {
				employeeMapper.deleteByPrimaryKey(Integer.parseInt(id));
			} catch (Exception e) {
				if (e.getLocalizedMessage().contains("customer_counterman"))
					return "删除失败！<br>员工有用户。";
				else
					return "删除失败！<br>系统异常。";
			}
		}

		this.init_EMPLOYEEMAP();

		// SysConst.initConstFor_QUERY("init_EMPLOYEEMAP");

		return "success";
	}

	@Override
	public SysEmployee getEmployeeById(Integer employeeId) {
		// TODO Auto-generated method stub

		return employeeMapper.selectByPrimaryKey(employeeId);
	}

	@Override
	public void init_EMPLOYEEMAP() {
		// TODO Auto-generated method stub

		SysConst.EMPLOYEE_MAP = new HashMap<Integer, String>();
		
		

		List<SysEmployee> employeeList = employeeMapper.selectByExample(null);

		for (SysEmployee e : employeeList) {

			SysConst.EMPLOYEE_MAP.put(e.getEmployeeId(), e.getEmployeeName());
		}

	}

	@Override
	public List<SysEmployeeEx> getEmployees() {
		// TODO Auto-generated method stub

		return this.convert(employeeMapper.selectByExample(null));
	}

	/**
	 * 根据员工姓名查找对应的Id
	 */
	@Override
	public List<Integer> getEmployeeIds(String employeeName) {

		List<Integer> eIdList = new ArrayList<Integer>();

		SysEmployeeExample example = new SysEmployeeExample();

		example.or().andEmployeeNameLike("%" + employeeName.trim() + "%");
		for (SysEmployee e : employeeMapper.selectByExample(example)) {
			eIdList.add(e.getEmployeeId());
		}

		return eIdList;
	}

	
	@Override
	public void exportExcel(SysEmployeeEx employee, OutputStream os) {
		
		
		SysEmployeeExample example = new SysEmployeeExample();

		Criteria criteria = example.createCriteria();
		

		this.setCriteria(employee, criteria);


		example.setOrderByClause(" work_group asc");
		List<SysEmployeeEx>  listEmployeeEx= this.convert(employeeMapper.selectByExample(example));
		
		
		ExportExcel<SysEmployeeEx> exportExcel = new ExportExcel<SysEmployeeEx>();
		
		exportExcel.exportExcel("导出嘉宾信息", SysConst.ExcelConst.HEAD_SYSEMPLOYEE,SysConst.ExcelConst.FIELDNAMES_SYSEMPLOYEE, listEmployeeEx, os,"yyyy-MM-dd");

		
	}

	@Override
	public SysEmployee getByCustomerName(String employeeName) {
		
		SysEmployeeExample example = new SysEmployeeExample();

		example.or().andEmployeeNameEqualTo(employeeName);


		List<SysEmployee> customers = employeeMapper.selectByExample(example);
		
		if(customers == null || customers.size() == 0)
			return null;

		return customers.get(0);
	}

	@Override
	public SysEmployee getByCellPhone(String cellPhone) {
		
		SysEmployeeExample example = new SysEmployeeExample();

		example.or().andEmployeeCellPhoneEqualTo(cellPhone);


		List<SysEmployee> customers = employeeMapper.selectByExample(example);
		
		if(customers == null || customers.size() == 0)
			return null;

		return customers.get(0);
	}

}
